package com.xc.utils.redis;

import com.google.common.collect.Lists;
import com.xc.utils.PropertiesUtil;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;

import java.util.List;

/**
 *  Redis 分片连接池
 * Created by xiongcan on 2018/1/22.
 */
public class RedisShardedPool {
    private static ShardedJedisPool pool;  //  sharded jedis 连接池
    //最大连接数
    private static Integer maxTotal = Integer
            .parseInt(PropertiesUtil.getProperty("redis.max.total","20"));
    //连接池中最大空闲
    private static Integer maxIdle = Integer
            .parseInt(PropertiesUtil.getProperty("redis.max.idle","10"));
    //连接池中最小空闲
    private static Integer minIdle = Integer
            .parseInt(PropertiesUtil.getProperty("redis.min.idle","2"));

    //  在拿实例的时候，是否要验证
    private static Boolean testOnBorrow = Boolean
            .parseBoolean(PropertiesUtil.getProperty("redis.test.borrow","true"));
    //  在还实例的时候，是否要验证
    private static Boolean testOnReturn = Boolean
            .parseBoolean(PropertiesUtil.getProperty("redis.test.return","true"));

    private static String redisIp1 = (PropertiesUtil.getProperty("redis1.ip"));
    private static Integer redisPort1 = Integer
            .parseInt(PropertiesUtil.getProperty("redis1.port"));

//    private static String redisIp2 = (PropertiesUtil.getProperty("redis2.ip"));
//    private static Integer redisPort2 = Integer
//            .parseInt(PropertiesUtil.getProperty("redis2.port"));

    //  初始化连接池 init pool
    private static void initPool(){
        JedisPoolConfig config = new JedisPoolConfig();

        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        config.setMinIdle(minIdle);

        config.setTestOnBorrow(testOnBorrow);
        config.setTestOnReturn(testOnReturn);

        //  连接耗尽时是否阻塞，true为阻塞，false为抛出异常
        config.setBlockWhenExhausted(true);

        List<JedisShardInfo> jedisShardInfos = Lists.newArrayList();
        JedisShardInfo info1 = new JedisShardInfo(redisIp1,redisPort1,1000 *2);//超时时间2s
        //如果redis有密码的话
        info1.setPassword(PropertiesUtil.getProperty("redis1.pwd"));
        jedisShardInfos.add(info1);

//        JedisShardInfo info2 = new JedisShardInfo(redisIp2,redisPort2,1000 *2);
        //info2.setPassword(xxx);
//        jedisShardInfos.add(info2);

        //  MURMUR_HASH对应的是一致性算法
        pool = new ShardedJedisPool(config,jedisShardInfos, Hashing.MURMUR_HASH
                , Sharded.DEFAULT_KEY_TAG_PATTERN);
    }

    //  在加载到jvm的时候就要初始化，使用静态代码块
    static {
        initPool();
    }

    //  从连接池郦拿实例
    public static ShardedJedis getJedis(){
        return pool.getResource();
    }
    //  把实例放回到连接池
    public static void returnResouce(ShardedJedis jedis){
        pool.returnResource(jedis);
    }
    //  把实例放回broken连接池
    public static void returnBrokenResouce(ShardedJedis jedis){
        pool.returnBrokenResource(jedis);
    }


    public static void main(String[] args) {
//        ShardedJedis shardedJedis = pool.getResource();
//        for (int i = 0; i < 10; i++){
//            shardedJedis.set("key" + i , "value" + i);
//        }
//        returnResouce(shardedJedis);
//        System.out.println("sharded jedis end...");
    }

}
